package com.exam.aspect;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdviceAdapter;

import java.lang.reflect.Type;

@Slf4j
@ControllerAdvice
@RequiredArgsConstructor
public class BodyAdvice extends RequestBodyAdviceAdapter {

    private final ObjectMapper objectMapper;

    /**
     * 判断该转换器是否支持处理指定的方法参数、目标类型和转换器类型
     *
     * @param methodParameter 方法参数
     * @param targetType 目标类型
     * @param converterType 转换器类型
     * @return 如果支持则返回true，否则返回false
     */
    @Override
    public boolean supports(MethodParameter methodParameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
        return true;
    }

    /**
     * 在读取请求体后执行的回调方法
     *
     * @param body 请求体对象
     * @param inputMessage HTTP输入消息
     * @param parameter 方法参数
     * @param targetType 目标类型
     * @param converterType 消息转换器类型
     * @return 返回处理后的请求体对象
     * @throws Exception 如果处理过程中发生异常，则抛出异常
     */
    @Override
    @SneakyThrows
    public Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter,
                                Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
        // 使用ObjectMapper将请求体对象转换成字符串并输出日志
        log.info("[Request body]: {}", objectMapper.writeValueAsString(body));
        // 调用父类的afterBodyRead方法，并返回处理后的请求体对象
        return super.afterBodyRead(body, inputMessage, parameter, targetType, converterType);
    }
}
